package com.atguigu.spzx.manager.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.atguigu.spzx.manager.mapper.SysUserMapper;
import com.atguigu.spzx.manager.service.SysUserService;
import com.atguigu.spzx.model.dto.system.LoginDto;
import com.atguigu.spzx.model.dto.system.SysUserDto;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.entity.system.SysUserThreadLocalAuthContextUtil;
import com.atguigu.spzx.model.vo.system.LoginVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;

@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;


    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /*
    * 这里简单处理一下登陆失败,返回为空,先跑通一次*/
    @Override
    public LoginVo login(LoginDto loginInfo) {
        //获取验证码,进行登录验证码校验
        String cacheCaptcha = redisTemplate.opsForValue().get(loginInfo.getCodeKey());
        Assert.isTrue(StringUtils.hasText(cacheCaptcha)&&cacheCaptcha.equals(loginInfo.getCaptcha()),"验证码错误!");
        //识别成功后删除验证码  (放这里有个问题,识别失败了之后删除不了,而且一直刷新验证码的话,redis数据也会一直增加.
        // 我觉得最终方案应该是设置验证码存活时长)
        redisTemplate.delete(loginInfo.getCodeKey());

        //用户账号密码校验
        SysUser user = sysUserMapper.selectByUserName(loginInfo.getUserName());
        //根据查询的内容进行判断是否登录成功
        //什么都没查到说明用户名就错了.
        Assert.notNull(user,"用户名或密码错误");
        //加密密码,去对比数据库的密码
        String passwordMd5= DigestUtils.md5DigestAsHex(loginInfo.getPassword().getBytes());
        Assert.isTrue(passwordMd5.equals(user.getPassword()), "密码错误");
        //到这里说明密码匹配,创建结果返回对象
        LoginVo loginVo=new LoginVo();
        String token = UUID.randomUUID().toString().replace("-","");
        //tonken和用户信息本来要存入缓存一份,我们可以根据该token查询到缓存里用户信息.
       // System.out.println("把数据跟token存入缓存一份");
        //将数据存入redis缓存  redis键值对数据库,我们存入一个key 和一个json的数据
        redisTemplate.opsForValue().set("user:login"+token, JSON.toJSONString(user, SerializerFeature.BrowserSecure));

        loginVo.setToken(token);
        loginVo.setRefresh_token("");
        return loginVo;
    }

    @Override
    public SysUser getUserInfo(String token) {
/*        //根据token从缓存中取出用户信息  把json格式的数据转换为对象
        String json = redisTemplate.opsForValue().get("user:login" + token);
        //排除json为空,即找不到的情况
        Assert.notNull(json,"Token无效");
        SysUser user = JSON.parseObject(json, SysUser.class);*/
/*        System.out.println("根据token从缓存中取出用户信息");
        SysUser user = new SysUser();
        user.setName("xiaoli");
        user.setUserName("xiaolizi");*/


        //最终解决方案是通过拦截器+threadlocal存储来处理的.
        SysUser user = SysUserThreadLocalAuthContextUtil.get();
        return user;
    }

    @Override
    public PageInfo<SysUser> getSysUserListByPage(Integer page, Integer limit, SysUserDto sysUserDto) {
        //开启分页查询
        PageHelper.startPage(page,limit);
        //查询数据
        List<SysUser> sysUserList = sysUserMapper.selectSysUserListByPage(sysUserDto);
        //封装数据并返回
        PageInfo<SysUser> pageInfo= new PageInfo<>(sysUserList);
        return pageInfo;
    }

    @Override
    public void updateSysUser(SysUser sysUser) {
        //修改用户信息不应该包括更改密码
        sysUserMapper.updateSysUser(sysUser);
    }

    @Override
    public void saveSysUser(SysUser sysUser) {
        //添加用户信息,注意这里的密码是明文,需要加密处理
        String password = sysUser.getPassword();
        String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
        sysUser.setPassword(md5Password);

        //这里有个字段status,暂时没有需求,但是数据库要求不能为空,我们这里暂时通过赋值处理一下
        sysUser.setStatus(1);
        sysUserMapper.insertSysUser(sysUser);
    }

    @Override
    public void deleteById(Long userId) {
        sysUserMapper.deleteById(userId);
    }

}
